package org.example.meetingsystem.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.meetingsystem.DTO.LoginDTO;
import org.example.meetingsystem.DTO.RegisterDTO;
import org.example.meetingsystem.DTO.UpdateUserDTO;
import org.example.meetingsystem.entity.User;
import org.example.meetingsystem.enums.UserRole;
import org.example.meetingsystem.enums.UserStatus;
import org.example.meetingsystem.mapper.UserMapper;
import org.example.meetingsystem.service.UserService;
import org.example.meetingsystem.util.BusinessException;
import org.example.meetingsystem.util.JwtUtil;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final JwtUtil jwtUtil;
    private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public Map<String, Object> login(LoginDTO loginDTO) {
        log.info("用户登录尝试: {}", loginDTO.getUsername());

        User user = userMapper.selectByUsername(loginDTO.getUsername());

        if (user == null) {
            log.warn("登录失败: 用户不存在 - {}", loginDTO.getUsername());
            throw new BusinessException("用户名或密码错误");
        }

        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            log.warn("登录失败: 密码错误 - {}", loginDTO.getUsername());
            throw new BusinessException("用户名或密码错误");
        }

        if (user.getStatus() != UserStatus.ACTIVE) {
            log.warn("登录失败: 账号状态异常 - {} 状态: {}", loginDTO.getUsername(), user.getStatus());
            throw new BusinessException("账号未激活或已被冻结");
        }

        String token = jwtUtil.generateToken(user);

        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("user", user);

        log.info("用户登录成功: {}", loginDTO.getUsername());
        return result;
    }

    @Override
    public void register(RegisterDTO registerDTO) {
        log.info("用户注册请求: {}", registerDTO.getUsername());

        // 检查用户名是否已存在
        User existUser = userMapper.selectByUsername(registerDTO.getUsername());
        if (existUser != null) {
            log.warn("注册失败: 用户名已存在 - {}", registerDTO.getUsername());
            throw new BusinessException("用户名已存在");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
        user.setName(registerDTO.getName());
        user.setRole(UserRole.CUSTOMER);
        user.setCompanyName(registerDTO.getCompanyName());
        user.setPhone(registerDTO.getPhone());
        user.setStatus(UserStatus.PENDING);
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        int result = userMapper.insert(user);
        if (result <= 0) {
            log.error("注册失败: 数据库插入失败 - {}", registerDTO.getUsername());
            throw new BusinessException("注册失败，请稍后重试");
        }

        log.info("用户注册成功: {}", registerDTO.getUsername());
    }

    @Override
    @Transactional(readOnly = true)
    public User findByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public Page<User> getUserList(int pageNum, int pageSize, String username, UserRole role, UserStatus status) {
        Page<User> page = new Page<>(pageNum, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        if (StringUtils.hasText(username)) {
            queryWrapper.like("username", username).or().like("name", username);
        }
        if (role != null) {
            queryWrapper.eq("role", role);
        }
        if (status != null) {
            queryWrapper.eq("status", status);
        }

        queryWrapper.orderByDesc("created_at");
        return userMapper.selectPage(page, queryWrapper);
    }

    @Override
    public User getUserById(Long userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public void updateUser(Long userId, UpdateUserDTO updateUserDTO) {
        User user = new User();
        user.setId(userId);
        user.setName(updateUserDTO.getName());
        user.setCompanyName(updateUserDTO.getCompanyName());
        user.setPhone(updateUserDTO.getPhone());
        user.setRole(updateUserDTO.getRole());
        userMapper.updateById(user);
    }

    @Override
    public void deleteUser(Long userId) {
        userMapper.deleteById(userId);
    }

    @Override
    public List<User> getPendingUsers() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", UserStatus.PENDING)
                .orderByAsc("created_at");
        return userMapper.selectList(queryWrapper);
    }

    @Override
    public Map<String, Object> getUserStatistics() {
        Map<String, Object> statistics = new HashMap<>();

        // 总用户数
        statistics.put("totalUsers", userMapper.selectCount(null));

        // 各状态用户数
        for (UserStatus status : UserStatus.values()) {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", status);
            statistics.put(status.getCode().toLowerCase() + "Users", userMapper.selectCount(queryWrapper));
        }

        // 各角色用户数
        for (UserRole role : UserRole.values()) {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("role", role);
            statistics.put(role.getCode().toLowerCase() + "Users", userMapper.selectCount(queryWrapper));
        }

        return statistics;
    }

    @Override
    public void updateUserStatus(Long userId, UserStatus status) {
        User user = new User();
        user.setId(userId);
        user.setStatus(status);
        userMapper.updateById(user);
    }
}